﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using static LiWi.Shell;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Diagnostics;
using System.Collections;
using System.Reflection;
using System.Xml.Linq;
using System.Security.Permissions;
using System.Xml.XPath;
using System.Globalization;
using System.Runtime.CompilerServices;



namespace LiWiTools
{
    public partial class ToolsForm : Form
    {
        private UserControlRoot rootControl;
        private UserControlFirst firstControl ;
        //控制器字典
        public static Dictionary<string, Data> controlDictionary=new Dictionary<string, Data>();
        public static readonly object controlDictionaryLock=new object();
        //控制器轴参数字典
        public static Dictionary<Data, DataControl> dataControl = new Dictionary<Data, DataControl>();
        public static Dictionary<Data, DataAxis> dataAxis = new Dictionary<Data, DataAxis>();
        //初始化根目录，一二级级目录字典
        private Dictionary<TreeNode, UserControlRoot> userRootDictionary;
        private Dictionary<TreeNode, UserControlFirst> userFirstDictionary;
        private Dictionary<TreeNode, UserControlSecend> userSecendDictionary;
       // private string NowNoteName;
        private string LastNoteName;
        public static string rootNodeName;
        Thread thUpAxis;
        private bool isResizing = false;    //IO窗口大小变换
        private System.Windows.Forms.Timer resizeTimer;




        public ToolsForm()
        {
            InitializeComponent();
            resizeTimer = new System.Windows.Forms.Timer();
            resizeTimer.Interval = 100;//设置延时时间
            resizeTimer.Tick += ResizeTimer_Tick;
            panel_Data.Resize += panel_Data_Resize;
        }
        private void ResizeTimer_Tick(object sender, EventArgs e)
        {
            resizeTimer.Stop();
            isResizing = false;
            //string rootNodeName;
            //treeViewSelect(out rootNodeName);
            if (rootNodeName != null)
            {
                Data IPName=controlDictionary[rootNodeName];
                // 检查 Data.NowWin 的值（注意：这里假设 Data.NowWin 的变化是线程安全的）
                if (IPName.NowWin == 2)
                {
                    UpDateIOWin();
                    //AddUserControlToPanel(IPName);
                    panel_Data.Controls.Clear();
                    rootControl.Show();
                    rootControl.Dock = DockStyle.Fill;
                    panel_Data.Controls.Add(rootControl);

                    //userFirstDictionary.DrawControl();
                }
            }
        }

        private void panel_Data_Resize(object sender,EventArgs e)
        {
            if (!isResizing)
            {
                isResizing = true;
                resizeTimer.Stop(); // 如果计时器已经在运行，则停止它
                resizeTimer.Start(); // 重新启动计时器
            }
        }

        ~ToolsForm()
        {
            thUpAxis.Abort();
            foreach (string ip in controlDictionary.Keys)
            {
                Data IPName = controlDictionary[ip];
                if (IPName.handle != IntPtr.Zero) PMC_Close(IPName.handle);
            }
        }

        private void ToolsForm_Load(object sender, EventArgs e)
        {
            Assembly assembly = Assembly.GetExecutingAssembly();
            AssemblyName assemblyName = assembly.GetName();
            Version version=assemblyName.Version;
            this.Text= "LIWITool "+version.ToString();
            DrawMenuStrip();
           

        }

        //MenuStrip菜单编制
        public void DrawMenuStrip()
        {
            //创建
            //MenuStrip menuStrip0 = new MenuStrip();
            //创建一级菜单
            ToolStripMenuItem first = new ToolStripMenuItem("控制器");
            ToolStripMenuItem secend = new ToolStripMenuItem("视图");
            ToolStripMenuItem third = new ToolStripMenuItem("工具栏");
            ToolStripMenuItem fourth = new ToolStripMenuItem("帮助");
            menuStrip.Items.Add(first);
            menuStrip.Items.Add(secend);
            menuStrip.Items.Add(third);
            menuStrip.Items.Add(fourth);
            List<ToolStripMenuItem> menu;
            //创建二级菜单
            //控制器            
            ToolStripMenuItem first0 = new ToolStripMenuItem("自动连接");
            ToolStripMenuItem first1 = new ToolStripMenuItem("手动连接");
            ToolStripMenuItem first2 = new ToolStripMenuItem("断开连接");
            menu = new List<ToolStripMenuItem>() { first0, first1, first2 };
            for (int i = 0; i < menu.Count; i++)
            {
                int Index = i;
                first.DropDownItems.Add(menu[i]);
                menu[i].Click += (sender, e) => Connect(Index);
            }
            menu.Clear();
            //first.DropDownItems.Add(first0);
            //first.DropDownItems.Add(first0);
            //first.DropDownItems.Add(first0);
            //first.DropDownItems.Add(first0);
            //视图
            ToolStripMenuItem secend0 = new ToolStripMenuItem("在线命令");
            ToolStripMenuItem secend1 = new ToolStripMenuItem("状态栏");
            menu = new List<ToolStripMenuItem>() { secend0, secend1 };
            for (int i = 0; i < menu.Count; i++)
            {
                int Index = i;
                menu[i].Checked = true;
                menu[i].CheckOnClick = true;
                secend.DropDownItems.Add(menu[i]);
                menu[i].Click += (sender, e) => ViewShow(Index);
            }
            menu.Clear();
            //工具栏
            ToolStripMenuItem third0 = new ToolStripMenuItem("IP修改");
            menu = new List<ToolStripMenuItem>() { third0 };
            for (int i = 0; i < menu.Count; i++)
            {
                int Index = i;
                third.DropDownItems.Add(menu[i]);
                menu[i].Click += (sender, e) => Tool(Index);
            }
            menu.Clear();
            //帮助
            ToolStripMenuItem fourth0 = new ToolStripMenuItem("LiWi工具使用手册");
            ToolStripMenuItem fourth1 = new ToolStripMenuItem("BASIC帮助");
            ToolStripMenuItem fourth2 = new ToolStripMenuItem("PC开发手册");

            menu = new List<ToolStripMenuItem> { fourth0, fourth1, fourth2 };
            for(int i = 0;i < menu.Count; i++)
            {
                int Index = i;
                fourth.DropDownItems.Add(menu[i]);
                menu[i].Click += (sender, e) => Help(Index);
            }
            menu.Clear();
            txt_Exe.KeyDown += new KeyEventHandler(txt_Exe_KeyDowm);
        }
        /// <summary>
        /// 连接
        /// </summary>
        /// <param name="mode">模式：0自动连接；1手动连接，2断开连接</param>
        async void Connect(int mode)
        {
                //PMC_Close(Data.handle);
                if (mode == 0)
                {
                    byte[] ipList = new byte[512];
                    int ret = PMC_SearchEthlist(ipList, 512, 200);   //查找IP

                if (ret == 0)
                {
                    string manyIP = System.Text.Encoding.Default.GetString(ipList);
                    manyIP = manyIP.Replace("\0", "");
                    string[] IPList = manyIP.Split(',');
                    foreach (var ip in IPList)
                    {
                        IntPtr handle = IntPtr.Zero;
                        ret= PMC_OpenEth(ip, ref handle);
                        if (!controlDictionary.ContainsKey(ip)&& ret==0)
                        {                            
                            lock (controlDictionaryLock)
                            {
                                controlDictionary[ip] = new Data();
                                controlDictionary[ip].handle = handle;
                                controlDictionary[ip].connectID = ip;
                                controlDictionary[ip].connectOver = true;
                            }                            
                            await connectSuccess(controlDictionary[ip]);
                        }
                        else if(ret != 0)
                        {
                            MessageBox.Show($"未能连接{ip}，请使用其他连接方式！！");
                        }
                    }
                }
                else
                {
                    MessageBox.Show("未查找到控制器，请使用其他连接方式！！");
                    return;
                }

                }
                else if (mode == 1)
                {
                    ConnectForm connectForm = new ConnectForm();
                    connectForm.ShowDialog();
                    if (connectForm.newConnect != null) await connectSuccess(controlDictionary[connectForm.newConnect]);
                }
                
                
            if (mode == 2)
            {
                //string rootNodeName;
                //treeViewSelect(out rootNodeName);
                if (rootNodeName != null)
                {
                    Data IPName=controlDictionary[rootNodeName];
                    if (IPName.connectOver)
                    {
                        CloseControl(IPName);
                        //controlDictionary.Remove(rootNodeName);
                    }
                    else MessageBox.Show("未连接控制器");
                }
            }
        }

        /// <summary>
        /// 连接成功后更新界面
        /// </summary>
        public async Task connectSuccess(Data IPName )
        {
            //设置卡超时时间
            PMC_SetTimeOut(IPName.handle, 100);
            //如果连接成功，打开RootWin界面
            //IO页面更新状态
            UpDateIOWin();
            ////根目录表格更新状态
            //UserControlRoot._viewFlag = false;
            //二级目录
            UserControlSecend.upView = false;
            //((ToolStripMenuItem)menuStrip.Items[0]).DropDownItems[0].Enabled = false;
            //((ToolStripMenuItem)menuStrip.Items[0]).DropDownItems[1].Enabled = false;

            //获取轴参数
            DataControl control = new DataControl();
            control.GetControlData(IPName);
            dataControl[IPName]= control;
            //更新目录
            treeMenu(IPName);
            //更新点位
            if (panel2.Enabled) AddPoints(IPName);
            //IPName.NowWin = 1;
            //AddUserControlToPanel(IPName);


            //await rootControl.AsyncUpdateWin();
            thUpAxis = new Thread(() =>
            {
                if (IPName.handle != IntPtr.Zero)
                {
                    DataAxis daAxis = new DataAxis();
                    while (IPName.handle != IntPtr.Zero)
                    {
                        dataAxis[IPName] = daAxis;
                        daAxis.GetAxisData(IPName, dataControl[IPName]);
                        
                    }
                }
                
            });
            thUpAxis.IsBackground = true;
            thUpAxis.Start();

            //lab_ConnectState.BackColor = Color.Green;
            //lab_ConnectState.Text = "已连接";
            //toolTip1.SetToolTip(lab_ConnectState, IPName.connectID);
            //PMC_SetTimeOut(IPName.handle, 1000);
        }



        public void CloseControl(Data IPName )
        {
            rootNodeName = null;
            IPName.connectOver = false;
            //lab_ConnectState.BackColor = Color.Red;
            //lab_ConnectState.Text = "未连接";
            //toolTip1.RemoveAll();
            thUpAxis.Abort();
            panel_Data.Controls.Clear();
            foreach(TreeNode RemoveNode in treeView.Nodes)
            {
                try
                {
                    if (RemoveNode.Text == IPName.connectID&& RemoveNode!=null) treeView.Nodes.Remove(RemoveNode);
                }
                catch
                { }
            }
            try
            {
                dataAxis[IPName].iniFlag = false;
                PMC_Rapidstop(IPName.handle, 3);
                PMC_Close(IPName.handle);
                IPName.handle = IntPtr.Zero;
            }
            catch
            { }

            dataAxis[IPName].errCodeDesc.Clear();
            dataControl.Remove(IPName);
            dataAxis.Remove(IPName);
            lock (ToolsForm.controlDictionaryLock)
            {
                controlDictionary.Remove(IPName.connectID);
               
            }
        }


        /// <summary>
        /// 视图
        /// </summary>
        /// <param name="num"></param>
        async void ViewShow(int num)
        {
            if (num == 0)
            {
                if (panel4.Visible == false) panel4.Visible = true;
                else panel4.Visible = false;
            }
            else if (num == 1)
            {
                if (panel2.Visible == false) panel2.Visible = true;
                else panel2.Visible = false;
            }
        }

        /// <summary>
        /// 工具栏
        /// </summary>
        /// <param name="num"></param>
        async void Tool(int num)
        {
            //string rootNodeName;
            //treeViewSelect(out rootNodeName);
            if (rootNodeName != null)
            {
                Data IPName=controlDictionary[rootNodeName];
                if (num == 0)
                {
                    SetIP setIP = new SetIP(IPName);
                    setIP.ShowDialog();
                    if (setIP.IPChange) Connect(2);
                }
            }
        }

        async void Help(int num)
        {
            string filePath;
            if (num == 0)
            {
                filePath = "LiWi工具使用手册.pdf";  //IDE平台开发手册
                try
                {
                    Process.Start(filePath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("LiWi工具使用手册打开失败：" + ex.Message);
                }
            }
            else if (num == 1)
            {
                filePath = "help.chm";  //IDE平台开发手册
                try
                {
                    Process.Start(filePath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("BASIC帮助打开失败：" + ex.Message);
                }
            }
            else if (num == 2)
            {                
                filePath = "LIWI PC编程手册.pdf";  //IDE使用手册
                try
                {
                    Process.Start(filePath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("PC开发手册打开失败：" + ex.Message);
                }
            }
        }

        /// <summary>
        /// 更新树状菜单
        /// </summary>
        void treeMenu(Data IPName)
        {
            //根节点
            TreeNode rootNode = new TreeNode(IPName.connectID);


            //一级节点
            TreeNode firstNode = new TreeNode("Local");

            //二级节点
            for (int i = 0; i < dataControl[IPName].axisVirtuAxises; i++)
            {
                TreeNode secondNode = new TreeNode($"Axis{i}");
                firstNode.Nodes.Add(secondNode);    //二级节点添加到一级中
            }
            //初始化字典
            userRootDictionary = new Dictionary<TreeNode, UserControlRoot>();
            userFirstDictionary = new Dictionary<TreeNode, UserControlFirst>();
            userSecendDictionary = new Dictionary<TreeNode, UserControlSecend>();
            rootNode.Nodes.Add(firstNode);          //一级节点添加到根节点
            treeView.BeginInvoke(new MethodInvoker(delegate
            {
                treeView.Nodes.Add(rootNode);           //根节点添加到控件
                //treeView.ExpandAll();                   //展开所有节点
            }));
        }

        /// <summary>
        /// 根状数点击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private async void treeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            //string rootNodeName;  
            //treeViewSelect(out rootNodeName);

            //if (rootNodeName == null)
            //{
            //    rootNodeName = e.Node.Text == null ? null : e.Node.Text;
            //}
            rootNodeName = e.Node.FullPath;
            int firstString = rootNodeName.IndexOf('\\');
            if (firstString != -1)   rootNodeName= rootNodeName.Substring(0, firstString);
            UpDateIOWin();
            if (rootNodeName != null)
            {
                Data IPName = controlDictionary[rootNodeName];
                TreeNode clickedNode = e.Node;
                //判断点击哪一节点
                if (clickedNode.Level == 0 &&( IPName.NowWin != 1||LastNoteName!=rootNodeName))    //根节点
                {
                    //IO页面更新状态
                    UpDateIOWin();

                    IPName.NowWin = 1;
                    IPName.secondNow = -1;
                    if (!userRootDictionary.TryGetValue(e.Node, out UserControlRoot rootControl))
                    {
                        rootControl = new UserControlRoot(IPName);
                        userRootDictionary[e.Node] = rootControl;
                    }
                    panel_Data.Controls.Clear();
                    rootControl.Show();
                    rootControl.Dock = DockStyle.Fill;
                    panel_Data.Controls.Add(rootControl);
                    await rootControl.AsyncUpdateWin();
                }
                else if (clickedNode.Level == 1 && (IPName.NowWin != 2 || LastNoteName != rootNodeName))    //一级节点
                {
                    IPName.NowWin = 2;
                    IPName.secondNow = -1;
                    if (!userFirstDictionary.TryGetValue(e.Node, out UserControlFirst firstControl))
                    {
                        firstControl = new UserControlFirst(IPName);
                        userFirstDictionary[e.Node] = firstControl;
                    }
                    panel_Data.Controls.Clear();
                    firstControl.Show();
                    firstControl.Dock = DockStyle.Fill;
                    panel_Data.Controls.Add(firstControl);
                    firstControl.DrawControl();
                }
                else if (clickedNode.Level == 2 && (IPName.secondNow != clickedNode.Index || LastNoteName != rootNodeName))    //二级节点
                {
                    //IO页面更新状态
                    UpDateIOWin();

                    IPName.NowWin = 3;
                    //清理现有控件
                    panel_Data.Controls.Clear();
                    IPName.secondNow = clickedNode.Index;
                    //如果字典中存在这个节点实例，直接使用
                    if (!userSecendDictionary.TryGetValue(e.Node, out UserControlSecend secondControl))
                    {
                        secondControl = new UserControlSecend(IPName);
                        userSecendDictionary[e.Node] = secondControl;
                    }
                    secondControl.Dock = DockStyle.Fill;
                    panel_Data.Controls.Add(secondControl);
                    await secondControl.UpAxisData(clickedNode.Index);
                }               
            }
            LastNoteName = rootNodeName;
        }

        public void UpDateIOWin()
        {
            if (firstControl != null)
            {
                //IO页面更新状态
                firstControl.drawIN = false;
                firstControl.drawOUT = false;
                firstControl.drawPWM = false;
                firstControl.drawAD = false;
            }
        }

        private TreeNode GetRootNode(TreeNode node)
        {
            if (node == null)
                return null; // 如果没有选中的节点，返回null

            TreeNode currentNode = node;
            // 遍历父节点链，直到找到根节点（Parent为null的节点）
            while (currentNode.Parent != null)
            {
                currentNode = currentNode.Parent;
            }
            // currentNode现在指向根节点
            return currentNode;
        }



        /// <summary>
        /// 把UserControl控件添加到Panel里
        /// </summary>
        /// <param name="WinType">1:Root,2:First,3:Secend</param>
        private void AddUserControlToPanel(UserControlRoot userControl)
        {
            panel_Data.Controls.Clear();
            userControl.Show();
            userControl.Dock = DockStyle.Fill;
            panel_Data.Controls.Add(userControl);
        }

        /// <summary>
        /// 更新指令栏
        /// </summary>
        public void UpdaLog( string message, bool warn=false)
        {
            int start= txt_Log.Text.Length;
            string text = $">>{message} \r\n";
            txt_Log.AppendText(text);
            if (warn)
            {
                txt_Log.Select(start, text.Length);
                txt_Log.SelectionColor=System.Drawing.Color.Red;
                txt_Log.SelectionStart=txt_Log.TextLength;
                txt_Log.SelectionLength = 0;
            }
        }

        /// <summary>
        /// 发送在线命令
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Send_Click(object sender, EventArgs e)
        {
            SendToOnLine();
        }
        private void txt_Exe_KeyDowm(object sender, KeyEventArgs e)
        {
            if (e.KeyCode==Keys.Enter)
            {
                SendToOnLine();
            }            
        }
        private void btn_Clean_Click(object sender, EventArgs e)
        {
            txt_Log.Clear();
        }



        /// <summary>
        /// 发送
        /// </summary>
        public void SendToOnLine()
        {
            //string rootNodeName;
            //treeViewSelect(out rootNodeName);
            if (rootNodeName != null)
            {
                Data IPName = controlDictionary[rootNodeName];
                UpdaLog( IPName+":"+ txt_Exe.Text);
                byte[] response = new byte[2048];
                int a = 0;
                //a= PMC_Command(Data.handle, txt_Exe.Text, response, 2048);

                a = PMC_Execute(IPName.handle, txt_Exe.Text, response, 2048);
                byte[] mesbyte = response.Where(b => b != '\0').ToArray();
                string mes = Encoding.ASCII.GetString(mesbyte);
                //分割字符
                string[] parts = mes.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
                string mesOUT = "";
                for (int i = 0; i < parts.Length; i++)
                {
                    if (parts[i] != "")
                    {
                        if (i == 0) mesOUT = parts[i];
                        else mesOUT += $", {parts[i]}";
                    }
                }
                if (a != 0)
                {
                    UpdaLog( $"{IPName} 执行错误，错误码为：{a.ToString()}", true);
                    return;
                }
                UpdaLog(mesOUT);
            }
        }
           

        /// <summary>
        /// 点位控件
        /// </summary>
        public void AddPoints(Data IPName)
        {
            Label _pointName=new Label();
            _pointName.Text = "坐标";
            _pointName.AutoSize = true;
            _pointName.Location = new System.Drawing.Point(60, 5);
            //添加到panel中
            panel2.Controls.Add(_pointName);



            for (int i = 0; i < dataControl[IPName].axisVirtuAxises; i++)
            {
                Label axis = new Label();
                Label axisPoint = new Label();
                axis.Text = $"[{i}]";
                axis.AutoSize = true;
                axis.Location = new System.Drawing.Point(90+75*i, 5);
                axisPoint.Name = "axisPoint" + i;
                axisPoint.Text = $"0.00";
                axisPoint.AutoSize = true;
                axisPoint.Location = new System.Drawing.Point(120+75*i, 5);
                panel2.Controls.Add(axis);
                panel2.Controls.Add(axisPoint);
            }
        }
        /// <summary>
        /// 更新点位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {            
            if (rootNodeName != null)
            {
                Data IPName = controlDictionary[rootNodeName];
                //实时更新点位
                if (IPName.handle != IntPtr.Zero && panel2.Enabled)
                {
                    for (int i = 0; i < dataControl[IPName].axisVirtuAxises; i++)
                    {
                        Control axisPoint = this.Controls.Find("axisPoint" + i, true).FirstOrDefault();
                        if (axisPoint != null && axisPoint is Label)
                        {
                            axisPoint.Text = $"{dataAxis[IPName].dPos[i]:F2}";
                        }
                    }
                }
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            bool remove=false;
            Data removeIPName=new Data();
            lock (controlDictionaryLock)
            {
                foreach (var item in controlDictionary.Keys)
                {
                    Data IPName;
                    if (controlDictionary.TryGetValue(item, out IPName))
                    {
                        if (IPName.handle != IntPtr.Zero && panel2.Enabled)
                        {
                            //监控心跳
                            byte state = 0;
                            Stopwatch stopwatch = new Stopwatch();
                            stopwatch.Start();
                            int ret1= PMC_GetState(IPName.handle, ref state);
                            long milliseconds = stopwatch.ElapsedMilliseconds;
                            if (ret1 != 0)
                            {                                
                                remove=true;
                                removeIPName = IPName;
                                double time = milliseconds;
                                break;
                            }
                            stopwatch.Stop();
                            byte[] buffer = new byte[20480];
                            uint retLength = 0;
                            int ret = PMC_ReadMessage(IPName.handle, buffer, (uint)(buffer.Length - 1), ref retLength);
                            if (ret == 0 && retLength > 0) // 如果读取成功并且读到的信息长度大于 0 则输出
                            {
                                string aa = System.Text.Encoding.ASCII.GetString(buffer, 0, (int)retLength);
                                UpdaLog(aa);
                            }

                        }
                    }

                }
            }
            if (remove)
            {
                CloseControl(removeIPName);
            }
            if (controlDictionary.Count>0&& lab_ConnectState.BackColor != Color.Green)
            {
                lab_ConnectState.BackColor = Color.Green;
                lab_ConnectState.Text = "已连接";
            }
            else if(controlDictionary.Count == 0 && lab_ConnectState.BackColor == Color.Green)
            {
                lab_ConnectState.BackColor = Color.Red;
                lab_ConnectState.Text = "未连接";
            }
        }

    }
}
